package com.nulldev.util.data.Arrays.arrays;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Spliterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;

public class HybridCopyOnWriteArrayList<T> extends ArrayList<T> {
	private static final long serialVersionUID = 8981936266987295015L;
	private final CopyOnWriteArrayList<T> underlyingList;

	public HybridCopyOnWriteArrayList() {
		super(0);
		this.underlyingList = new CopyOnWriteArrayList<T>();
	}

	public HybridCopyOnWriteArrayList(final int size) {
		super(0);
		this.underlyingList = new CopyOnWriteArrayList<T>();
	}

	public HybridCopyOnWriteArrayList(final Collection<? extends T> list) {
		super(0);
		this.underlyingList = new CopyOnWriteArrayList<T>(list);
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		return this.underlyingList.containsAll(c);
	}

	@Override
	public boolean equals(Object o) {
		return this.underlyingList.equals(o);
	}

	@Override
	public int hashCode() {
		return this.underlyingList.hashCode();
	}

	@Override
	public void add(int index, T element) {
		this.underlyingList.add(index, element);
	}

	@Override
	public boolean add(T e) {
		return this.underlyingList.add(e);
	}

	@Override
	public boolean addAll(Collection<? extends T> c) {
		return this.underlyingList.addAll(c);
	}

	@Override
	public boolean addAll(int index, Collection<? extends T> c) {
		return this.underlyingList.addAll(index, c);
	}

	@Override
	public void clear() {
		this.underlyingList.clear();
	}

	@Override
	public boolean contains(Object o) {
		return this.underlyingList.contains(o);
	}

	@Override
	public Object clone() {
		return this.underlyingList.clone();
	}

	@Override
	public void ensureCapacity(int minCapacity) {
	}

	@Override
	public void forEach(Consumer<? super T> action) {
		this.underlyingList.forEach(action);
	}

	@Override
	public T get(int index) {
		return this.underlyingList.get(index);
	}

	@Override
	public int indexOf(Object o) {
		return this.underlyingList.indexOf(o);
	}

	@Override
	public int lastIndexOf(Object o) {
		return this.underlyingList.lastIndexOf(o);
	}

	@Override
	public boolean isEmpty() {
		return this.underlyingList.isEmpty();
	}

	@Override
	public Iterator<T> iterator() {
		return this.underlyingList.iterator();
	}

	@Override
	public ListIterator<T> listIterator() {
		return this.underlyingList.listIterator();
	}

	@Override
	public ListIterator<T> listIterator(int index) {
		return this.underlyingList.listIterator(index);
	}

	@Override
	public Stream<T> parallelStream() {
		return this.underlyingList.parallelStream();
	}

	@Override
	public T remove(int index) {
		return this.underlyingList.remove(index);
	}

	@Override
	public boolean remove(Object o) {
		return this.underlyingList.remove(o);
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		return this.underlyingList.removeAll(c);
	}

	@Override
	public boolean removeIf(Predicate<? super T> filter) {
		return this.removeIf(filter);
	}

	@Override
	public void replaceAll(UnaryOperator<T> operator) {
		this.underlyingList.replaceAll(operator);
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		return this.underlyingList.retainAll(c);
	}

	@Override
	public T set(int index, T element) {
		return this.underlyingList.set(index, element);
	}

	@Override
	public int size() {
		return this.underlyingList.size();
	}

	@Override
	public void sort(Comparator<? super T> c) {
		this.underlyingList.sort(c);
	}

	@Override
	public Spliterator<T> spliterator() {
		return this.underlyingList.spliterator();
	}

	@Override
	public Stream<T> stream() {
		return this.underlyingList.stream();
	}

	@Override
	public List<T> subList(int fromIndex, int toIndex) {
		return this.underlyingList.subList(fromIndex, toIndex);
	}

	@Override
	public Object[] toArray() {
		return this.underlyingList.toArray();
	}

	@SuppressWarnings("hiding")
	public <T> T[] toArray(T[] o) {
		return this.underlyingList.toArray(o);
	}

	@Override
	public void trimToSize() {
	}

	@Override
	public String toString() {
		return this.underlyingList.toString();
	}
}
